package org.study.redis.boot.config;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.core.*;
import tools.jackson.core.json.JsonReadFeature;
import tools.jackson.databind.*;
import tools.jackson.databind.ext.javatime.deser.*;
import tools.jackson.databind.ext.javatime.ser.*;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.module.SimpleModule;
import tools.jackson.databind.ser.std.ToStringSerializer;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 作用描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2024年11月04日
 */
@Configuration
public class ObjectMapperConfig {
    /*@Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 注册JavaTimeModule以支持Java8日期时间类型
        objectMapper.registerModule(new JavaTimeModule());
        // 设置全局日期格式
        objectMapper.configOverride(LocalDateTime.class)
                .setFormat(new JsonFormat.Value().withPattern("yyyy-MM-dd HH:mm:ss"));
        objectMapper.configOverride(LocalDate.class)
                .setFormat(new JsonFormat.Value().withPattern("yyyy-MM-dd"));
        objectMapper.configOverride(LocalTime.class)
                .setFormat(new JsonFormat.Value().withPattern("HH:mm:ss"));
        // 启用写入时间戳
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 忽略未知属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注册自定义序列化模块
        SimpleModule module = new SimpleModule();
        // 将Long转为字符串，避免前端数据精度丢失
        module.addSerializer(Long.class, new ToStringSerializer());
        module.addSerializer(long.class, new ToStringSerializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }*/
    @Bean
    public JsonMapper jsonMapper() {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule
                // 设置全局日期格式
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)))
                .addSerializer(Date.class, new ValueSerializer<>() {
                    @Override
                    public void serialize(Date value, JsonGenerator generator, SerializationContext provider) throws JacksonException {
                        String formatted = DateUtil.format(value, DatePattern.NORM_DATETIME_PATTERN);
                        generator.writeString(formatted);
                    }
                })
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)))
                .addDeserializer(Date.class, new ValueDeserializer<>() {
                    @Override
                    public Date deserialize(JsonParser parser, DeserializationContext context) throws JacksonException {
                        String parserText = parser.getText();
                        return DateUtil.parse(parserText, DatePattern.NORM_DATETIME_PATTERN);
                    }
                })
                // 将Long转为字符串，避免前端数据精度丢失
                .addSerializer(Long.class, ToStringSerializer.instance)
                .addSerializer(Long.TYPE, ToStringSerializer.instance)
                .addSerializer(long.class, ToStringSerializer.instance);

        return JsonMapper.builder().addModule(simpleModule)
                // 允许出现单引号
                .enable(JsonReadFeature.ALLOW_SINGLE_QUOTES)
                // 允许未转义控制字符
                .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
                // 忽略未知属性
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                // .propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
                .build();
    }
}
